﻿using System;
using System.Collections.Generic;
using Opalis.QuickIntegrationKit;
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Exchange.WebServices.Autodiscover;
using System.Text;
using System.Net;

namespace ExchangeMail
{
    [OpalisObject("Read Mail From Folder")]
    public class ReadMail : IOpalisObject
    {
        private MailboxSettings settings;
        private String maxNumberOfEmails = "100";
        private String exchangeVersion = String.Empty;
        private String userName = String.Empty;
        private String password = String.Empty;
        private String domain = String.Empty;
        private String folderName = String.Empty;
        private FolderId folderID = new FolderId(WellKnownFolderName.Inbox);
        private String serviceURL = String.Empty;

        [OpalisConfiguration]
        public MailboxSettings Settings
        {
            get { return settings; }
            set { settings = value; }
        }


        public void Design(IOpalisDesigner designer)
        {
            designer.AddInput("Folder Name").WithDefaultValue("Inbox");
            designer.AddInput("Max Number of Emails").NotRequired().WithDefaultValue("100");
            designer.AddOutput("Number of Emails").AsString();
            designer.AddCorellatedData(typeof(Email));
        }

        public void Execute(IOpalisRequest request, IOpalisResponse response)
        {
            userName = settings.UserName;
            password = settings.Password;
            domain = settings.Domain;
            serviceURL = settings.ServiceUrl;
            exchangeVersion = settings.ExchangeVersion;

            folderName = request.Inputs["Folder Name"].AsString();
            maxNumberOfEmails = request.Inputs["Max Number of Emails"].AsString();

            try
            {
                Convert.ToInt32(maxNumberOfEmails);
            }
            catch
            {
                maxNumberOfEmails = "100";
            }

            ExchangeService service = new ExchangeService();
            switch (exchangeVersion)
            {
                case "Exchange2007_SP1":
                    service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
                    break;
                case "Exchange2010":
                    service = new ExchangeService(ExchangeVersion.Exchange2010);
                    break;
                case "Exchange2010_SP1":
                    service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
                    break;
                default:
                    service = new ExchangeService();
                    break;
            }

            service.Credentials = new WebCredentials(userName, password, domain);
            String AccountUrl = userName + "@" + domain;

            if (serviceURL.Equals("Autodiscover")) { service.AutodiscoverUrl(AccountUrl); }
            else { service.Url = new Uri(serviceURL); }

            SearchFilter filter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, folderName);
            FolderView view = new FolderView(int.MaxValue);
            view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
            view.PropertySet.Add(FolderSchema.DisplayName);
            view.Traversal = FolderTraversal.Deep;
            FindFoldersResults results = service.FindFolders(WellKnownFolderName.MsgFolderRoot, filter, view);

            foreach (Folder folder in results)
            {
                folderID = folder.Id;
                break;
            }

            FindItemsResults<Item> findResults = service.FindItems(folderID, new ItemView(Convert.ToInt32(maxNumberOfEmails)));

            response.Publish("Number of Emails", findResults.Items.Count.ToString());
            response.WithFiltering().PublishRange(getMail(findResults, service));
        }

        private IEnumerable<Email> getMail(FindItemsResults<Item> findResults, ExchangeService service)
        {
            foreach (Item result in findResults)
            {
                if (result.GetType().ToString().Equals("Microsoft.Exchange.WebServices.Data.EmailMessage"))
                {
                    EmailMessage message = EmailMessage.Bind(service, result.Id);
                    String body = message.Body.ToString();
                    String from = message.From.Address.ToString();
                    String subject = message.Subject.ToString();
                    String id = message.Id.ToString();
                    DateTime recievedDate = message.DateTimeReceived;
                    Boolean Attachments = message.HasAttachments;
                    yield return new Email(subject, body, from, id, recievedDate, Attachments);
                }
            }
        }
    }
}
